/***********************************************************************************
 * 文件名： encrypt.c
 * 作者： 刘言
 * 版本： 20200828
 * 说明：
 * 		一些简单的加密算法。
 * 		
 * 修改记录：
 * 	20200828: 初版
***********************************************************************************/
#include "polsys.h"
#include "encrypt.h"

// 字节加密密钥，分别为第n位在对应密文字节的位置
static C51_CODE const u8 BIT_LOCAL[8] = ECPT_BYTE_KEY;  

// 把8字节密文解密成1个字节
// ctext: 8字节密文
u8 Ecpt_DecryptByte(u8 * ctext)
{
    u8 i;
    u8 dat = 0;
    u8 bitinfo;
    u8 *uid = ULock_GetUid();
    for(i=0;i<8;i++)    // 从第0位开始解密 ，第0位的信息保存在ctext[0]，且被uid[1]再次加密
    {
        dat >>= 1;
        bitinfo = ctext[i] - uid[i+1];      // 得到与uid无关的密文
        bitinfo = bitinfo & BIT_LOCAL[i];   // 取出对应位的值
        if(bitinfo) dat |= 0x80;        // 保存到原始数据的位置
    }
    return dat;
}

// 把1个字节加密成8字节的数组
// 注意ctext长度 >= 8
void Ecpt_EncryptByte(u8 byte,u8 * ctext)
{
    u8 i;
    u8 bitinfo;
    u8 *uid = ULock_GetUid();
    for(i=0;i<8;i++)    // 从第0位开始加密，第0位的信息保存在ctext[0]，且被uid[1]再次加密
    {
        bitinfo = GetRand8bit();                    // 取一个随机数
        bitinfo = bitinfo & (~BIT_LOCAL[i]);        // 清零第i位所在位置
        if(byte & (1<<i))bitinfo |= BIT_LOCAL[i];   // 将数据的第i位（如果为1）保存在对应位置
        ctext[i] = bitinfo + uid[i+1];              // 得到与UID有关的密文
    }
}



// 加密数据
// passcode:作为密码加密数据
// len: 数据长度  
// buff:数据。 
void Ecpt_EncryptData(u8 *buff,u8 len, u8 passcode)
{
	u8 i;

	passcode = passcode ^ ECPT_DATA_KEY1;
	for(i = 0; i < len; i++)
	{
		buff[i] = buff[i] ^ passcode;
		passcode = ((passcode << 3) | (passcode >> 5)) ^ ECPT_DATA_KEY0;
	}
}


// 解密数据，还原被 Ecpt_EncryptData 加密过的数据
// passcode:8bit密码 
// len:数据长度  
// dat:数据。 
void Ecpt_DecryptData(u8 passcode, u8 len, u8 *dat)
{
	u8 i;

	if(passcode == 0) return;
	passcode = passcode ^ ECPT_DATA_KEY1;
	for(i = 0; i < len; i++)
	{
		passcode = ((passcode << 3) | (passcode >> 5)) ^ ECPT_DATA_KEY0;
	}
	do
	{
		len--;
		passcode = passcode ^ ECPT_DATA_KEY0;
		passcode = ((passcode >> 3) | (passcode << 5));
		dat[len] = dat[len] ^ passcode;
	}while(len > 0);
}


// 计算一段数据的“认证码”
// buff： 数据
// len：数据长度
u8 Ecpt_GetAuthCode(const u8 * buff,u8 len)
{
	u8 temp=0;
	
	temp = GetSum_U8(buff, len);
	return ((ECPT_AUTH_KEY * temp) ^ temp);
}

// 计算一段数据的“回应码”
IN_LINE u8 Ecpt_GetBackCode(const u8 * buff,u8 len)
{
	return GetSum_U8(buff, len);
}
